package cn.ailearn.module.service.impl;

import cn.ailearn.exception.ServiceException;
import cn.ailearn.module.mapper.UsersMapper;
import cn.ailearn.module.pojo.entity.Users;
import cn.ailearn.module.service.UsersService;
import cn.ailearn.security.details.MySysUserDetails;
import cn.ailearn.utils.JWTUtils;
import cn.ailearn.utils.RedisUtils;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static cn.ailearn.constant.RedisConstants.RedisExpire.THIRTY_MINUTES_EXPIRE;

/**
* @author Administrator
* @description 针对表【users(用户表)】的数据库操作Service实现
* @createDate 2025-10-23 15:13:02
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements UsersService{


    private final AuthenticationManager authenticationManager;

    private final RedisUtils redisUtils;

    @Override
    public String login(String username, String password) {

        if (ObjectUtil.isEmpty(username) || ObjectUtil.isEmpty(password)) {
            throw new ServiceException("用户名或密码不能为空");
        }

        MySysUserDetails mySysUserDetails = getMySysUserDetails(username, password);

        // 生成token
        Long userId = mySysUserDetails.getUsers().getId();
        HashMap<String, Object> claims = new HashMap<>();
        claims.put("user_id", userId);
        String token = JWTUtils.createToken(claims);

        String redisKey = UsersService.getUserInfoRedisKey(userId);
        // 缓存用户信息,有效期为30分钟
        redisUtils.setCacheObject(redisKey, JSONUtil.toJsonStr(mySysUserDetails), THIRTY_MINUTES_EXPIRE, TimeUnit.MINUTES);

        return token;
    }

    @Override
    public boolean loginOut() {
//        Long userId = BaseContext.getCurrentId();
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        MySysUserDetails mySysUserDetails = covertMySysUserDetail(authentication);

        Long userId = mySysUserDetails.getUsers().getId();
        String redisKey = UsersService.getUserInfoRedisKey(userId);
        // 删除缓存中的用户信息
        redisUtils.deleteObject(redisKey);
        return true;
    }

    // 获取用户信息
    private MySysUserDetails getMySysUserDetails(String username, String password){
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(username, password);
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);

        return covertMySysUserDetail(authenticate);
    }

    /**
     * 转换为MySysUserDetails
     * @param authenticate
     * @return
     */
    private static MySysUserDetails covertMySysUserDetail(Authentication authenticate) {
        if (Objects.isNull(authenticate)) {
            throw new ServiceException("登录失败");
        }

        Object principal = authenticate.getPrincipal();
        MySysUserDetails mySysUserDetails = null;
        if (principal instanceof MySysUserDetails) {
            mySysUserDetails = (MySysUserDetails) principal;
        }

        return mySysUserDetails;
    }


}




